package com.zagj.videocomparess;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.ImageFormat;
import android.graphics.Point;
import android.hardware.Camera;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;


import com.zagj.videocomparess.encode.AudioEncoder;
import com.zagj.videocomparess.utils.FFmpegHandle;
import com.zagj.videocomparess.utils.MediaLive;
import com.zagj.videocomparess.utils.PreviewCameara;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Author : eric
 * CreateDate : 2017/11/6  10:57
 * Email : ericli_wang@163.com
 * Version : 2.0
 * Desc :
 * Modified :
 */

public class CameraVideoActivity extends Activity implements SurfaceHolder.Callback, Camera.PreviewCallback {
    private SurfaceView sv;
    private int screenWidth = 320;
    private int screenHeight = 240;
    private SurfaceHolder mHolder;
    private Camera mCamera;
    public String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath() + File.separator;
    private String mSavePath = path + "wsAddMusic.mp4";
    boolean isPreview = false; // 是否在浏览中
    private String dir = "CameraDemo1";
    //private String url = "rtmp://192.168.43.122:1935/zbcs/room";
    private String url = "rtmp://192.168.1.35/live/test";
    //采集到每帧数据时间
    long previewTime = 0;
    //开始编码时间
    long encodeTime = 0;
    //采集数量
    int count = 0;
    //编码数量
    int encodeCount = 0;

    boolean isPlaying = false;

    Button btn_start;
    private int frequence = 44100;
    //CHANNEL_IN_MONO	������
    private int channelConfig = AudioFormat.CHANNEL_IN_STEREO;//CHANNEL_IN_STEREO//CHANNEL_IN_MONO
    private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

    private CameraVideoActivity.Config config;
    private CameraSizeComparator cameraSizeComparator;
    private Button btn_start2;
    boolean recording = false;
    private RecordTask recordTask;
    private AudioEncoder audioEncoder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_video);
        btn_start = (Button) findViewById(R.id.btn_start);
        btn_start2 = (Button) findViewById(R.id.btn_start2);
        btn_start2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MediaLive.getInstance().openUrl(mSavePath, url);
            }
        });
        btn_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isPlaying) {
                    isPlaying = false;
                    recording=false;
                    btn_start.setText("start");
                } else {
                    isPlaying = true;
                    recording=true;
                    btn_start.setText("stop");
                    recordTask.execute();

                }
            }
        });
        init();
    }

    private void init() {
        config = new Config();
        config.minPreviewWidth = 720;
        config.minPictureWidth = 720;
        config.rate = 1.778f;
        cameraSizeComparator = new CameraSizeComparator();
        MediaLive.init(this);
        sv = (SurfaceView) findViewById(R.id.sv);
        mHolder = sv.getHolder();
        mHolder.addCallback(this);
        MediaLive.getInstance().initVideo(url);
        recordTask=new RecordTask();

        // MediaLive.getInstance().openUrl(mSavePath,url);

      /*  audioEncoder = new AudioEncoder();
        try {
            audioEncoder.prepare();
            audioEncoder.setAudioDataCallback(new AudioEncoder.AudioDataCallback() {
                @Override
                public void onDataCallback(byte[] audiodata, int length) {
                    MediaLive.getInstance().startAudio(audiodata, length);
                    //MediaLive.getInstance().startAudio(audiodata, length);
                }
            });
            audioEncoder.start();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        MediaLive.getInstance().stop();
    }

    @Override
    protected void onResume() {
        super.onResume();
      /*  if (mCamera == null) {
            mCamera = getCamera();
            if (mHolder != null) {
                setStartPreview(mCamera, mHolder);
            }
        }*/
    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseCamera();
    }

    private Camera getCamera() {
        Camera camera;
        try {
            //打开相机，默认为后置，可以根据摄像头ID来指定打开前置还是后置
            camera = Camera.open(1);
            if (camera != null && !isPreview) {
                try {
                    Camera.Parameters parameters = camera.getParameters();
                    //对拍照参数进行设置
                    for (Camera.Size size : parameters.getSupportedPictureSizes()) {
                        Log.d("123", size.width + "  " + size.height);
                    }
                    camera.setPreviewCallback(this); // 设置回调的类
                    Log.d("123", "============");
                  /*  parameters.setPreviewSize(screenWidth, screenHeight); // 设置预览照片的大小
                   // parameters.setPreviewFpsRange(30000, 30000);
                    parameters.setPictureFormat(ImageFormat.NV21); // 设置图片格式
                    parameters.setPictureSize(screenWidth, screenHeight); // 设置照片的大小
                    camera.setParameters(parameters);*/
                    //parameters.setPreviewFpsRange(30000, 30000);
                    parameters.setPictureFormat(ImageFormat.NV21);
                    Camera.Size propPreviewSize = getPropPreviewSize(parameters.getSupportedPreviewSizes(), config.minPictureWidth, config.rate);
                    Camera.Size propPictureSize = getPropPictureSize(parameters.getSupportedPictureSizes(), config.minPictureWidth, config.rate);
                    parameters.setPreviewSize(propPreviewSize.width, propPreviewSize.height);
                    parameters.setPictureSize(propPictureSize.width, propPictureSize.height);
                    camera.setParameters(parameters);
                    //指定使用哪个SurfaceView来显示预览图片
                    camera.setPreviewDisplay(sv.getHolder()); // 通过SurfaceView显示取景画面


                    camera.startPreview(); // 开始预览
                    //Camera.takePicture()方法进行拍照
                    camera.autoFocus(null); // 自动对焦
                } catch (Exception e) {
                    e.printStackTrace();
                }
                isPreview = true;
            }
        } catch (Exception e) {
            camera = null;
            e.printStackTrace();
            Toast.makeText(this, "无法获取前置摄像头", Toast.LENGTH_LONG);
        }
        return camera;
    }

    public static void followScreenOrientation(Context context, Camera camera) {
        final int orientation = context.getResources().getConfiguration().orientation;
        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
        } else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
            camera.setDisplayOrientation(90);
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        //getCamera();
        // setStartPreview(mCamera, mHolder);

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        //setStartPreview(mCamera, mHolder);
        if (mCamera == null) {
            mCamera = getCamera();
            if (mHolder != null) {
                setStartPreview(mCamera, mHolder);
            }
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        releaseCamera();
    }


    private void setStartPreview(Camera camera, SurfaceHolder holder) {
        try {

            camera.setPreviewDisplay(holder);
            followScreenOrientation(this, camera);
            camera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /*
    释放相机资源
     */
    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    private Camera.Size getPropPictureSize(List<Camera.Size> supportedPictureSizes, int minPictureWidth, float rate) {
        Collections.sort(supportedPictureSizes, cameraSizeComparator);
        int i = 0;
        for (Camera.Size size : supportedPictureSizes) {
            if (size.height >= minPictureWidth && equalRate(size, rate)) {
                break;
            }
            i++;
        }
        if (i == supportedPictureSizes.size()) {
            i = 0;
        }
        return supportedPictureSizes.get(i);
    }

    private Camera.Size getPropPreviewSize(List<Camera.Size> supportedPictureSizes, int minPictureWidth, float rate) {
        Collections.sort(supportedPictureSizes, cameraSizeComparator);
        int i = 0;
        for (Camera.Size size : supportedPictureSizes) {
            if (size.height >= minPictureWidth && equalRate(size, rate)) {
                break;
            }
            i++;
        }
        if (i == supportedPictureSizes.size()) {
            i = 0;
        }
        return supportedPictureSizes.get(i);
    }

    private boolean equalRate(Camera.Size size, float rate) {
        float reaRate = (float) size.width / (float) size.height;
        if (Math.abs(reaRate - rate) <= 0.03) {
            return true;
        } else {
            return false;
        }
    }

    class Config {
        float rate; //宽高比
        int minPreviewWidth;
        int minPictureWidth;
    }

    private class CameraSizeComparator implements Comparator<Camera.Size> {
        public int compare(Camera.Size lhs, Camera.Size rhs) {
            // TODO Auto-generated method stub
            if (lhs.height == rhs.height) {
                return 0;
            } else if (lhs.height > rhs.height) {
                return 1;
            } else {
                return -1;
            }
        }

    }

    ExecutorService executor = Executors.newSingleThreadExecutor();

    @Override
    public void onPreviewFrame(final byte[] data, Camera camera) {
        if (isPlaying) {
            long endTime = System.currentTimeMillis();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    if (data == null) return;
                    encodeTime = System.currentTimeMillis();

                    int ret = MediaLive.getInstance().onFrameCallback(data);
                    if (ret == 0) {

                    }
                    // MediaLive.getInstance().onFrameCallback(data);
                    Log.w("Log", "编码第:" + (encodeCount++) + "帧，耗时:" + (System.currentTimeMillis() - encodeTime));
                }
            });
            Log.d("Log", "采集第:" + (++count) + "帧，距上一帧间隔时间:"
                    + (endTime - previewTime) + "  " + Thread.currentThread().getName());
            previewTime = endTime;
        }
    }

    class RecordTask extends AsyncTask<Void, android.R.integer, Void> {

        @Override
        protected Void doInBackground(Void... params) {

            int bufferSize = AudioRecord.getMinBufferSize(frequence, channelConfig, audioEncoding);
            //int bufferSize = 1024;
            AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    frequence, channelConfig, audioEncoding, bufferSize);
            //��ʼ¼��
            record.startRecording();

            byte[] bb = new byte[bufferSize];
            while (recording) {

                int size = record.read(bb, 0, bufferSize);
                if (size > 0) {

                    MediaLive.getInstance().startAudio(bb, size);
                    Log.e("TAG", "doInBackground: ");
                }
            }
            if (record.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
                record.stop();
            }
            record.release();
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            //stop.setText("�Ѿ�ֹͣ��");
        }
    }
}
